#include <QtCore/QString>
#include <QtTest/QtTest>
#include <QDebug>
#include <stdlib.h>
#include <botan/botan.h>
#include <botan/rsa.h>
#include <botan/oids.h>
#include "PublicKey.h"
#include "KeyManager.h"

using namespace kryptos::cryptography;
using namespace kryptos::entities;

class KeyManagerTest : public QObject
{
    Q_OBJECT

public:
    KeyManagerTest(){}

private Q_SLOTS:

    void createRSAKey();
    void loadKeyFormKeyring();
    void importPublicKey();
    void listAllKeys();
    void sharePublicCertificate();
    void searchKeys();

    void initTestCase();
    void cleanupTestCase();

private:

    std::string name, email, id, passphrase;
};

void KeyManagerTest::initTestCase()
{
    QFile::remove("kryptos_keyring.k");

    name = "sebastian";
    email = "superpacko@gmail.com";
    passphrase = "sebastian";
}

void KeyManagerTest::createRSAKey()
{
    KeyInfo info(KeyInfo::RSA, name, email, "test", passphrase, 1024);

    QVERIFY2(0 == KeyManager::instance().createAndStoreKey(info), "Error creating key!!");

    id = info.keyid();
}

void KeyManagerTest::loadKeyFormKeyring()
{
    PrivateKey key = KeyManager::instance().findKey(email, passphrase);

    QVERIFY2(key.info().email() == email, "Error retrieving key!!");

    qDebug() << key.info().keyid().c_str();

    // usando qbytearray
    Botan::AutoSeeded_RNG rng;
    Botan::AlgorithmIdentifier algoId(Botan::OIDS::lookup("RSA"), Botan::AlgorithmIdentifier::USE_NULL_PARAM);
    Botan::MemoryVector<Botan::byte> bytes((const unsigned char*)key.key().constData(), key.key().size());

    std::auto_ptr<Botan::RSA_PrivateKey> pk(new Botan::RSA_PrivateKey(algoId, bytes, rng));
    QVERIFY2(pk->check_key(rng, false), "Error checking key!!");

    // usando directamente botan_RSA_PrivateKey
    //QVERIFY2(key.key()->check_key(rng, false), "Error checking key!!");
}

void KeyManagerTest::importPublicKey()
{/*
    int r = KeyManager::instance().addPublicKey("botankey.asc");
    QVERIFY2(0 == r, "Error importing public key!");

    std::vector<KeyInfo> infolist = KeyManager::instance().allKeys();
    //std::for_each(infolist.begin(), infolist.end(), [](KeyInfo k){ qDebug() << k.email().c_str();});

    QVERIFY2(1 == 1, "Wrong!!");*/
}

void KeyManagerTest::listAllKeys()
{
    std::vector<KeyInfo> infolist = KeyManager::instance().allKeys();
    QByteArray hash = QCryptographicHash::hash(QByteArray(passphrase.c_str()), QCryptographicHash::Sha1);

    QVERIFY2(1 == infolist.size(), "Error listing keys!!");
    QVERIFY2(infolist.at(0).passphrase() == QString(hash.data()).toStdString(), "Wrong passphrase hash!!");
}

void KeyManagerTest::sharePublicCertificate()
{
    X509Certificate pubcert = KeyManager::instance().generatePublicKeyCert(email, passphrase);
    QVERIFY2(!pubcert.string().empty(), "Error generating certificate!");
}

void KeyManagerTest::searchKeys()
{
    QVERIFY2(KeyManager::instance().hasKeyWithEmail(email), "Error searching for key by email!");
    QVERIFY2(KeyManager::instance().hasKeyWithNameAndEmail(name, email), "Error searching for key by name and email!");
    QVERIFY2(KeyManager::instance().hasKeyWithId(id), "Error searching for key by id!");
}

void KeyManagerTest::cleanupTestCase()
{
}

QTEST_MAIN(KeyManagerTest);

#include "KeyManagerTest.moc"
